package com.lmx.persistence.service;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lmx.common.util.JavaMailUtil;
import com.lmx.repoDomain.tmodel.Account;
import com.lmx.repoDomain.tmodel.Dicttype;
import com.lmx.repoDomain.tmodel.PageInfo;
import com.lmx.repoDomain.tmodel.Role;
import com.lmx.repoDomain.tmodel.TypegroupTenant;
import com.lmx.repoDomain.tmodel.business.User;

import io.katharsis.queryParams.QueryParams;
import io.katharsis.queryParams.RestrictedPaginationKeys;

/**
 * Created by qin on 2016/8/9.
 */
@Service
public class CommonService {
	private Log logger = LogFactory.getLog(this.getClass());
	@PersistenceContext
	private EntityManager em;

	@Resource(name = "jdbcTemplate")
	private JdbcTemplate jdbcTemplate;

	protected JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	/**
	 * 获取系统用户
	 */
	public User getSystemUser() {
		// User systemUser = this.em.find(User.class,1000L);
		User systemUser = (User) this.em.createQuery("select u from User u where u.role.code = ?1 ")
				.setParameter(1, "system").getSingleResult();
		return systemUser;
	}

	/**
	 * 获取管理员用户
	 */
	public User getAdminUser(Long tenantId) {
		User systemUser=null;
		List resultList = this.em.createQuery("select u from User u where u.role.code = ?1 and u.tenant.id=?2")
				.setParameter(1, "admin").setParameter(2, tenantId).getResultList();
		if (resultList.size() > 0) {
			systemUser = (User) resultList.get(0);
		}
//		User systemUser = (User) this.em.createQuery("select u from User u where u.role.code = ?1 and u.tenant.id=?2")
//				.setParameter(1, "admin").setParameter(2, tenantId).getSingleResult();
		return systemUser;
	}

	/**
	 * 获取每天可提现次数
	 */
	public int getAllowWithdrawNum() {
		double num = (Double) this.em.createQuery("select c.value from Charge c where c.code = ?1")
				.setParameter(1, "withdrawCashDayTimes").getSingleResult();
		return (int) num;
	}

	/**
	 * 获取平台提佣比例
	 */
	public double getProportion() {
		double proportion = (Double) this.em.createQuery("select c.value from Charge c where c.code = ?1")
				.setParameter(1, "proportionOfPlatform").getSingleResult();
		return proportion;
	}

	/**
	 * 获取平台成单提佣比例
	 */
	public double getOrderCommissionProp() {
		double proportion = (Double) this.em.createQuery("select c.value from Charge c where c.code = ?1")
				.setParameter(1, "orderCommissionScale").getSingleResult();
		return proportion;
	}

	/**
	 * 获取客服角色
	 */
	public Role getCSRole() {
		Role role = (Role) this.em.createQuery("select r from Role r where r.code = ?1")
				.setParameter(1, "reg-customer_service").getSingleResult();
		return role;
		// return this.em.find(Role.class,2L);
	}

	/**
	 * 获取企业角色
	 */
	public Role getEntRole() {
		Role role = (Role) this.em.createQuery("select r from Role r where r.code = ?1")
				.setParameter(1, "reg-enterprises").getSingleResult();
		return role;
		// return this.em.find(Role.class,1L);
	}

	/**
	 * 获取可提现时间（week）
	 */
	public ArrayList<Integer> getWeek() {
		String weekStr = (String) this.em.createQuery("select c.value from Conf c where c.code = ?1")
				.setParameter(1, "week").getSingleResult();
		String[] weekStrs = weekStr.split(",");
		ArrayList<Integer> weeks = new ArrayList<Integer>();
		for (int i = 0; i < weekStrs.length; i++) {
			weeks.add(Integer.parseInt(weekStrs[i]));
		}
		return weeks;
	}

	/**
	 * 获取conf表内容
	 */
	public Integer getConfByCode(String code) {
		String codeStr = (String) this.em.createQuery("select c.value from Conf c where c.code = ?1")
				.setParameter(1, code).getSingleResult();
		return Integer.parseInt(codeStr);
	}

	/*    *//**
			 * 获取任务提醒通知email
			 */
	/*
	 * public String getEmailForTask(){ String email =
	 * this.em.find(User.class,1001L).getEmail();//debugTest return email; }
	 *
	 *//**
		 * 获取用户审核提醒，充值提现通知email
		 *//*
		 * public String getEmailForVerifyUserAndPay(){ String email =
		 * this.em.find(User.class,1002L).getEmail();//debugTest return email; }
		 */

	/**
	 * 运营提醒
	 *
	 * @param subject
	 * @param content
	 */
	public void operateRemind(String subject, String content) {
		ArrayList<String> emails = (ArrayList<String>) this.em
				.createQuery("select u.email from User u where u.role.code = ?1").setParameter(1, "operator")
				.getResultList();
		for (int i = 0; i < emails.size(); i++) {
			JavaMailUtil.getInstance().doSendHtmlEmail(subject, content, emails.get(i));
		}
	}

	/**
	 * 获取系统支出账户
	 */
	public Account getSysOutAccount() {
		Account sysOutAccount = (Account) this.em.createQuery("select a from Account a where a.code = ?1")
				.setParameter(1, "wx_out_platAccout").getSingleResult();
		return sysOutAccount;
	}

	/**
	 * 获取系统收入账户
	 */
	public Account getSysInAccount() {
		Account sysInAccount = (Account) this.em.createQuery("select a from Account a where a.code = ?1")
				.setParameter(1, "wx_in_platAccout").getSingleResult();
		return sysInAccount;
	}

	/**
	 * 获取每分钟通话费用
	 */
	public double getCustomerCallBill() {
		double bill = (Double) this.em.createQuery("select c.value from Charge c where c.code = ?1")
				.setParameter(1, "customerCallBill").getSingleResult();
		return bill;
	}

	/**
	 * 获取邀请佣金比例
	 */
	public double getInvitationCommissionProp() {
		double prop = (Double) this.em.createQuery("select c.value from Charge c where c.code = ?1")
				.setParameter(1, "invitationCommission").getSingleResult();
		return prop;
	}

	/**
	 * 获取相应字典
	 */
	public Dicttype getDicttype(String typecode) {
		Dicttype Dicttype = (Dicttype) this.em.createQuery("select d from Dicttype d where d.typecode = ?1")
				.setParameter(1, typecode).getSingleResult();
		return Dicttype;
	}

	/**
	 * 获取相应字典
	 */
	public Dicttype getDicttypeById(Long id) {
		Dicttype Dicttype = (Dicttype) this.em.createQuery("select d from Dicttype d where d.id = ?1")
				.setParameter(1, id).getSingleResult();
		return Dicttype;
	}
	/**
	 * 获取相应字典
	 */
	public List getDicttypeByGroup(String group) {
		List resultList = this.em.createQuery("select d from Dicttype d where d.delStatus != ?1 and d.typegroup.typegroupcode = ?2 ")
				.setParameter(1, (short)1).setParameter(2, group).getResultList();
		return resultList;
	}
	/**
	 * 获取统计分析口径
	 */
	public List getStatItemByType(String type) {
		List resultList = this.em
				.createQuery(
						"select c.statItem from StatQueryType c where  c.statType.typecode=?1  and c.delStatus != ?2 ")
				.setParameter(1, type).setParameter(2, (short) 1).getResultList();

		return resultList;
	}

	/**
	 * 获取租户字典分类
	 */
	public TypegroupTenant getTenantTypeGroup(String typecode) {
		TypegroupTenant group = (TypegroupTenant) this.em
				.createQuery("select d from TypegroupTenant d where d.typegroupcode = ?1").setParameter(1, typecode)
				.getSingleResult();
		return group;
	}

	/**
	 * 批量插入
	 */
	@Transactional
	public void batchInsert(List list) {
		for (int i = 0; i < list.size(); i++) {
			em.persist(list.get(i));
			if (i % 30 == 0) {
				em.flush();
				em.clear();
			}
		}
	}

	/**
	 * 批量更新
	 */
	@Transactional
	public void batchUpdate(List list) {
		for (int i = 0; i < list.size(); i++) {
			em.merge(list.get(i));
			if (i % 30 == 0) {
				em.flush();
				em.clear();
			}
		}
	}

	/**
	 * 批量插入 jdbc
	 */
	@Transactional
	public void patchInsertItems(String sql) {
		getJdbcTemplate().execute(sql);
	}

	@Transactional
	public void deleteEntity(String table, String filed, Long id, List ids) {
		//NursingProjectServiceItem
		if (table != null && filed != null && id != null) {
			String query ="";
			if("NursingProjectServiceItem".equals(table) || "CustomerActivityProjectItem".equals(table)){
				query = "update " + table + " rp set rp.delStatus=1 where rp." + filed + ".id = ?1 ";
			}else{
				query = "delete from " + table + " rp where rp." + filed + ".id = ?1 ";
			}
			if (ids != null && ids.size() > 0) {
				query += "and rp.id not in(:ids)";
				this.em.createQuery(query).setParameter(1, id).setParameter("ids", ids).executeUpdate();
			} else {
				this.em.createQuery(query).setParameter(1, id).executeUpdate();
			}
		}
	}


	  /**
     * 设置分页信息
     * @param List
     * @param requestParams
     */
    public boolean setPageInfo(List data,QueryParams requestParams){
        Map<RestrictedPaginationKeys,Integer> pagintion = requestParams.getPagination();// 获取分页参数
        if(pagintion.size() == 0) return false;

        int totalCount = data.size();// 总条数
        if(totalCount == 0) return false;
        int currPage = PageInfo.getInstance().getCurrPage();// 当前页
        int pageSize = PageInfo.getInstance().getSize();// 分页条数
        int startNum = PageInfo.getInstance().getStartNum(); //当前页开始条数
        int endNum = pageSize-1;// 当前页结束条数
        if(pagintion.get(RestrictedPaginationKeys.number) != null){
            currPage = pagintion.get(RestrictedPaginationKeys.number);
        }
        if(pagintion.get(RestrictedPaginationKeys.size) != null) {
            pageSize = pagintion.get(RestrictedPaginationKeys.size);
        }
        int totalPage = (totalCount + pageSize -1)/pageSize; //计算总页数
        if(currPage > totalPage) currPage = totalPage;
        startNum = pageSize * (currPage - 1) + 1;// 计算当前页开始条数
        endNum = startNum + pageSize -1; // 计算当前页结束条数
        if(endNum > totalCount) endNum = totalCount;

        // 设置分页信息
        PageInfo.getInstance().setTotalCount(totalCount);
        PageInfo.getInstance().setCurrPage(currPage);
        PageInfo.getInstance().setSize(pageSize);
        PageInfo.getInstance().setTotalPage(totalPage);
        PageInfo.getInstance().setStartNum(startNum);
        PageInfo.getInstance().setEndNum(endNum);
        return true;
    }

	  /**
     * 获取分页信息
     * @param List
     * @param requestParams
     */
    public List getPageData(List data,QueryParams requestParams){
    	List data1=new ArrayList<>();
        Map<RestrictedPaginationKeys,Integer> pagintion = requestParams.getPagination();// 获取分页参数
        if(pagintion.size() == 0) return data;

        int totalCount = data.size();// 总条数
        if(totalCount == 0) return null;
        int t= PageInfo.getInstance().getStartNum();
        int t2= PageInfo.getInstance().getEndNum();
        for(int i=t-1;i<totalCount&&i<t2;i++){
        	data1.add(data.get(i));
        }
       return data1;
    }

	/**
	* 复制源对象和目标对象的属性值
	*
	*/
	public static void copy(Object source, Object target) throws NoSuchMethodException, SecurityException,
			IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class sourceClass = source.getClass();// 得到对象的Class
		Class targetClass = target.getClass();// 得到对象的Class
		Field[] sourceFields = sourceClass.getDeclaredFields();// 得到Class对象的所有属性
		Field[] targetFields = targetClass.getDeclaredFields();// 得到Class对象的所有属性
		for (Field sourceField : sourceFields) {
			String name = sourceField.getName();// 属性名
			Class type = sourceField.getType();// 属性类型
			String methodName = name.substring(0, 1).toUpperCase() + name.substring(1);
			Method getMethod = sourceClass.getMethod("get" + methodName);// 得到属性对应get方法
			Object value = getMethod.invoke(source);// 执行源对象的get方法得到属性值
			for (Field targetField : targetFields) {
				String targetName = targetField.getName();// 目标对象的属性名
				if (targetName.equals(name)) {
					Method setMethod = targetClass.getMethod("set" + methodName, type);// 属性对应的set方法
					setMethod.invoke(target, value);// 执行目标对象的set方法
				}
			}
		}
	}

}
